#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
using namespace std;
/*通信就是进程间的数据同步

1、内核提供的通信方式（传统的通信方式）
    a.无名管道
    b.有名管道
    c.信号
2、system V提供的通信方式
    a.消息队列
    b.共享内存
    c.信号量（信号灯集）
3、套接字通信：socket 网络通信（跨主机通信）


linux系统的文件类型
文件类型：bcd-lsp
b:块设备文件
c：字符设备文件
d：目录文件，文件夹
-：普通文件
l：链接文件
s：套接字文件（网络编程）
p：管道文件


管道是一种特殊文件
无名管道：没有名字的管道，会在内核空间的内存缓冲区中创建一个管道文件(生命周期与进程一样)
         只能用于具有亲缘关系的进程之间通信(父进程和子进程)

语法：
 #include <unistd.h>

 int pipe(int fildes[2]);
 功能：创建一个无名管道，并返回该管道的两个文件描述符
 参数：是一个整型数组，用于返回打开的管道的两端的文件描述符， fildes[0]表示读端,fildes[1]表示写端
 返回值：成功返回0，失败返回-1并置位错误码
*/
/*
管道通信特点

1、管道可以实现自己给自己发消息
2、对管道中数据的操作是一次性的，当管道中的数据被读取后，就从管道中消失了，再读取时会被阻塞
3、管道文件的大小：64KB
4、由于返回的是管道文件的文件描述符，所以对管道的操作只能是文件IO相关函数，但是，不可以使用
 lseek对光标进行偏移，必须做到先进先出
5、管道的读写特点：
  当读端存在时：写端有多少写多少，直到写满64kB后，在write处阻塞
  当读端不存在时：写端再向管道中写入数据时，会发生管道破裂，内核空间会向用户空间发射一个
  SIGPIPE信号，进程收到该信号后，退出
  当写端存在时：读端有多少读多少，没有数据，会在read出阻塞
  当写端不存在时：读端有多少读多少，没有数据，不会在read处阻塞了,继续执行
6、管道通信是半双工通信方式
  单工：只能进程A向B发送消息
  半双工：同一时刻只能A向B发消息
  全双工：任意时刻，AB可以互相通信
*/
int main(int argc, const char *argv[])
{
    // 要在fork之前创建管道，这样fork后父子进程才用同一个管道
    // 不过父子进程的文件描述符值相同但不是同一个，但是指向的是同一个管道文件
    int fildes[2];
    if (pipe(fildes) == -1)
    {
        perror("pipe error");
        return -1;
    }
    printf("read:fildes[0]=%d\nwrite:fildes[1]=%d\n", fildes[0], fildes[1]); // 3  4

    pid_t pid = fork();
    if (pid > 0)
    {
        // 父进程
        // 不用读端就关闭
        close(fildes[0]);

        char wbuf[128] = "hello world";
        write(fildes[1], wbuf, strlen(wbuf));

        close(fildes[1]); // 关闭写端
        wait(NULL);       // 等待回收子进程
    }
    else if (pid == 0)
    {
        // 子进程
        // 不用写端就关闭
        close(fildes[1]);

        char rbuf[128];
        int ret = read(fildes[0], rbuf, sizeof(rbuf));
        if (ret == -1)
        {
            perror("read error");
            return -1;
        }

        printf("子进程读到的数据:%s\n", rbuf);
        close(fildes[0]); // 关闭读端
        exit(0);
    }
    else
    {
        printf("fork error");
        return -1;
    }
}